/* winaudio.h */

/********************/
/* SOUND-INTERFACE  */
/* for MS-Windows   */
/* (C) 2003 by NAH6 */
/********************/

#ifndef __WINAUDIO_H
#define __WINAUDIO_H
#ifdef __cplusplus
extern "C" {
#endif

/*------------*/
/*  INCLUDES  */
/*------------*/

#include <windows.h>
#include <mmsystem.h>

#include "sound.h"

/*-----------*/
/*  DEFINES  */
/*-----------*/

#define E_AUDIO_NULLPTR       (-0x7201)
#define E_AUDIO_PAR_BUFLEN    (-0x7202)
#define E_AUDIO_PAR_TRIGGER   (-0x7203)
#define E_AUDIO_PAR_RATE      (-0x7204)
#define E_AUDIO_PAR_WINCHUNK  (-0x7205)
#define E_AUDIO_NOMEM         (-0x7206)
#define E_AUDIO_THREAD        (-0x7207)
#define E_AUDIO_PRIO          (-0x7208)
#define E_AUDIO_CLOSE         (-0x7209)
#define E_AUDIO_FREE          (-0x720A)
#define E_AUDIO_INTERNAL      (-0x720B)
#define E_AUDIO_MM_UNKNOWN    (-0x720C)
#define E_AUDIO_MM_INTERNAL   (-0x720D)
#define E_AUDIO_MM_NOMEM      (-0x720E)
#define E_AUDIO_MM_INUSE      (-0x720F)
#define E_AUDIO_MM_FORMAT     (-0x7210)
#define E_AUDIO_MM_NOSOFT     (-0x7211)

/*====*/

#define K_AUDIO_MAXDEVIN            (8)
#define K_AUDIO_MAXDEVOUT           (8)
#define K_AUDIO_MAXDEVMIX           (4)
#define K_AUDIO_MAXMIXOUT           (8)
#define K_AUDIO_MAXMIXIN           (16)
#define K_AUDIO_MAXMIXCTRL          (8)
#define K_AUDIO_MAXMIXCHAN          (8)
#define K_AUDIO_MAXMIXITEM         (32)
#define K_AUDIO_MAXPORTIN           (4)
#define K_AUDIO_MAXPORTOUT          (4)

#define K_AUDIO_DEVICE_NOHW      (0x00)
#define K_AUDIO_DEVICE_OK        (0x01)
#define K_AUDIO_DEVICE_ERROR     (0xFF)

#define K_AUDIO_FLAGINDADA       (0x01)
#define K_AUDIO_FLAGINSTOP       (0x02)
#define K_AUDIO_FLAGINEND        (0x04)
#define K_AUDIO_FLAGINOVR        (0x08)

#define K_AUDIO_FLAGOUTDADA      (0x01)
#define K_AUDIO_FLAGOUTSTOP      (0x02)
#define K_AUDIO_FLAGOUTEND       (0x04)

#define K_AUDIO_OSTATE_SYNTH     (0x00)
#define K_AUDIO_OSTATE_VOICEDOWN (0x01)
#define K_AUDIO_OSTATE_VOICEUP   (0x02)

#define K_AUDIO_STDVOLUME      (0xFFFF)
#define K_AUDIO_OUTIDLETIME     (80000)

/*----*/

#ifndef _WIN32_WCE  /*Win98=24 WinCE=247*/
  #define K_AUDIO_INTPRIO     (THREAD_PRIORITY_NORMAL)
#else
  #define K_AUDIO_INTPRIO     (247)
#endif

/*--------------*/
/*  STRUCTURES  */
/*--------------*/

struct audio_hwinfo_wavein
{
  unsigned char valid;
  WAVEINCAPS    caps;
};


struct audio_hwinfo_waveout
{
  unsigned char valid;
  WAVEOUTCAPS   caps;
};


#ifndef _WIN32_WCE
struct audio_hwinfo_mixer
{
  unsigned char valid;
  MIXERCAPS     caps;
};
#endif


#ifndef _WIN32_WCE
struct audio_hwinfo_sigline
{
  unsigned char valid;
  MIXERLINE     caps;
};
#endif

/*--*/

struct audio_hwinfo
{
  struct audio_hwinfo_wavein  wavein [K_AUDIO_MAXDEVIN];
  struct audio_hwinfo_waveout waveout[K_AUDIO_MAXDEVOUT];
#ifndef _WIN32_WCE
    struct audio_hwinfo_mixer   mixer  [K_AUDIO_MAXDEVMIX];
    struct audio_hwinfo_sigline sigline[K_AUDIO_MAXDEVMIX] \
                                       [K_AUDIO_MAXMIXOUT][K_AUDIO_MAXMIXIN+1];
#endif
};


struct audio_hwconfig
{
  unsigned char  devin_wave;
  unsigned char  devin_mixmap;
  unsigned char  devin_mixdev;
  unsigned char  devin_mixout;
  unsigned char  devin_mixin [K_AUDIO_MAXPORTIN];
  unsigned short devin_mixlvl[K_AUDIO_MAXPORTIN];

  unsigned char  devout_wave;
  unsigned char  devout_mixmap;
  unsigned char  devout_mixdev[K_AUDIO_MAXPORTOUT];
  unsigned char  devout_mixout[K_AUDIO_MAXPORTOUT];
  unsigned char  devout_mixin [K_AUDIO_MAXPORTOUT];
  unsigned short devout_mixlvl[K_AUDIO_MAXPORTOUT];
};


struct audio_openopt
{
  unsigned long  bufferlen;
  unsigned short triggerlvl;
  unsigned char  samplerate;
  unsigned char  winchunks;
  struct sound_dseg *sound;
};

/*----*/

#ifndef _WIN32_WCE
struct audio_mixctrlinfo
{
  unsigned char valid;
  unsigned char dchan;
  unsigned char ditem;
  unsigned char dsize;
  MIXERCONTROL  ctrlinfo;
};
#endif

/*--*/

struct audio_mixoutinfo
{
#ifndef _WIN32_WCE
  struct audio_mixctrlinfo info[K_AUDIO_MAXMIXIN+1][K_AUDIO_MAXMIXCTRL];
#else
  unsigned char dummy;
#endif
};

/*====*/

struct audio_dseg
{
  /* Config-Info */
  struct audio_hwconfig hwconfig;

  /* Wave-Data */
  struct audio_openopt openopt;
  CRITICAL_SECTION     wavlock;
  HANDLE               intthread;
  DWORD                intthreadid;
  HANDLE               hdrevtbuf[2];
  /*** Audio-Input ***/
  HWAVEIN           inhandle;
  HANDLE            inpcmevt;
  unsigned char     inflags;
  unsigned long     inpcmwr;
  unsigned long     inpcmrd;
  signed   short   *inpcmbuf;
  volatile WAVEHDR *inhdrint;
  unsigned char     inhdrpos;
  WAVEHDR           inhdrbuf[3];
  signed   short   *inhdrpcm;
  /*** Audio Output ***/
  HWAVEOUT          outhandle;
  HANDLE            outpcmevt;
  unsigned char     outflags;
  unsigned long     outpcmwr;
  unsigned long     outpcmrd;
  signed   short   *outpcmbuf;
  volatile WAVEHDR *outhdrint;
  unsigned char     outhdrpos;
  WAVEHDR           outhdrbuf[3];
  signed   short   *outhdrpcm;
  unsigned char     outstate;
  unsigned long     outidle;

  /* Mixer-Data */
  CRITICAL_SECTION         mixlock;
  unsigned char            mixin_sel;
  struct audio_mixoutinfo *mixin_info;
  void                    *mixin_bak;
  struct audio_mixoutinfo *mixout_info[K_AUDIO_MAXPORTOUT];
  void                    *mixout_bak [K_AUDIO_MAXPORTOUT];
};

/*--------------*/
/*  PROTOTYPES  */
/*--------------*/

void audio_hwdetect  (struct audio_hwinfo *info);
void audio_hwautocfg (struct audio_hwconfig *config, \
                      const struct audio_hwinfo *info);

signed short audio_install   (struct audio_dseg *dseg, \
                              const struct audio_hwconfig *config);
signed short audio_remove    (struct audio_dseg *dseg);
signed short audio_getconfig (const struct audio_dseg *dseg, \
                              struct audio_hwconfig *config);

/*----*/

signed short audio_open    (struct audio_dseg *dseg, \
                            const struct audio_openopt *opt);
signed short audio_close   (struct audio_dseg *dseg);
signed short audio_wipe    (struct audio_dseg *dseg);
signed short audio_restart (struct audio_dseg *dseg);

/*----*/

signed short audio_instop  (struct audio_dseg *dseg);
signed short audio_instart (struct audio_dseg *dseg);
signed short audio_inclear (struct audio_dseg *dseg);
signed short audio_inlen   (struct audio_dseg *dseg, unsigned long *len);
signed short audio_inget   (struct audio_dseg *dseg, signed short *data, \
                            unsigned long *len, unsigned char wait);

signed short audio_outclear (struct audio_dseg *dseg, unsigned char soft);
signed short audio_outlen   (struct audio_dseg *dseg, unsigned long *len);
signed short audio_output   (struct audio_dseg *dseg,                      \
                             const signed short *data, unsigned long *len, \
                             unsigned char wait);

/*----*/

signed short audio_firstinport (const struct audio_dseg *dseg, \
                                unsigned char *port);
signed short audio_chkinport   (const struct audio_dseg *dseg, \
                                unsigned char *port);
signed short audio_getinmux    (const struct audio_dseg *dseg, \
                                unsigned char *port);
signed short audio_setinmux    (struct audio_dseg *dseg, \
                                unsigned char port);
signed short audio_getinvol    (const struct audio_dseg *dseg, \
                                unsigned char port, unsigned short *vol);
signed short audio_setinvol    (struct audio_dseg *dseg, \
                                unsigned char port, unsigned short vol);

signed short audio_firstoutport (const struct audio_dseg *dseg, \
                                 unsigned char *port);
signed short audio_chkoutport   (const struct audio_dseg *dseg, \
                                 unsigned char *port);
signed short audio_getoutvol    (struct audio_dseg *dseg, \
                                 unsigned char port, unsigned short *vol);
signed short audio_setoutvol    (struct audio_dseg *dseg, \
                                 unsigned char port, unsigned short vol);

#ifdef __cplusplus
}
#endif
#endif


/*** EOF ***/
